using Game.Networking;
using Game.Networking.Client;
using Game.Networking.Server;
using SMGCore;
using System;
using System.Collections.Generic;
using UnityEngine.UI;

namespace Game.UI {
	public enum WindowType {
		None,
		ChatWindow,
		DebugWindow,
		ProgramWindow,
		ShipConsoleWindow,
		ShipInfoWindow,
		UnitStatusWindow,
		ShipCommandsWindow,
		NoticeWindow,
		SettingsWindow,
		HelpWindow,
		CreateFileWindow
	}

	public class UIHolder : ManualSingleton<UIHolder> {
		const int BaseSortingOrder = 10;

		public bool HasFocus { get; set; }

		public UIClickInterceptor BackgroudFill;

		public List<UIWindow> Windows = new List<UIWindow>();

		public NoticeWindow NoticeWindow;

		protected IComputingUnitUserDataProvider _dataProvider;

		public void HideAllWindows() {
			foreach ( var w in Windows ) {
				w.gameObject.SetActive(false);
			}
			HasFocus = false;
		}

		public void HideWindow(WindowType window) {
			foreach ( var w in Windows ) {
				if ( w.WindowType == window ) {
					w.gameObject.SetActive(false);
				}
			}
		}

		public void ShowWindow(WindowType window) {
			var w = GetWindow(window);
			if ( w != null ) {
				w.gameObject.SetActive(true);
				MoveWindowToTop(w);
				w.OnWindowShow();
				HasFocus= true;
			}
		}

		public UIWindow GetWindow(WindowType window) {
			foreach ( var w in Windows ) {
				if ( w.WindowType == window ) {
					return w;
				}
			}
			return null;
		}

		public void ShowNoticeWindow(string title, string description, bool showHideButton, Action confirmAction, Action declineAction = null) {
			var window = GetWindow(WindowType.NoticeWindow);
			if ( window == null ) {
				return;
			}
			var w = (NoticeWindow)window;
			w.Setup(title, description, showHideButton, confirmAction, declineAction);
			w.ShowWindow();
		}

		protected override void Awake() {
			base.Awake();
			BackgroudFill.OnClick.AddListener(OnLoseFocusButtonClick);
			NoticeWindow.HideWindow();
		}

		protected virtual void Start() {
			HideAllWindows();

			_dataProvider.OnAttachedEntityIdChanged.Subscribe(this, OnAttachedEntityChanged);
		}

		public void AddWindow(UIWindow window) {
			Windows.Add(window);
		}

		public void RemoveWindow(UIWindow window) {
			Windows.Remove(window);
		}

		public void MoveWindowToTop(UIWindow window) {
			var index = GetWindowIndex(window);
			if (index == -1) {
				return;
			}
			if ( index == Windows.Count - 1 ) {
				return;
			}
			Windows.RemoveAt(index);
			Windows.Add(window);
			SortWindows();
		}

		void SortWindows() {
			foreach ( var w in Windows ) {
				w.transform.SetAsLastSibling();
			}
		}

		int GetWindowIndex(UIWindow window) {
			for ( int i = 0; i < Windows.Count; i++ ) {
				if ( Windows[i] == window ) {
					return i;
				}
			}
			return -1;
		}

		void OnLoseFocusButtonClick() {
			HasFocus= false;
		}

		void OnAttachedEntityChanged(uint entityId) {
			Entity e = null;
			if ( GameManager.Instance.IsServer ) {
				e = ServerEntityController.Instance.GetEntityById(entityId);
			} else {
				e = ClientEntityController.Instance.GetEntityById(entityId);
			}
			var cam = SpectatorCamera.Instance;
			if ( cam == null ) {
				return;
			}
			if ( e != null ) {
				cam.ConfineTarget = e.transform;
				cam.CenterToTarget();
			} else {
				cam.ConfineTarget = null;
			}
		}
	}
}
